﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ResourceBlender.Express.Validators;
using System.Globalization;
using ResourceBlender.Core;

namespace ResourceBlender.Express {
    /// <summary>
    /// A set of controls which allows editing of a translation, it's associated comment and performing actions such as searching and auto-translating
    /// </summary>
    public partial class TranslationInput : UserControl {
        public static readonly DependencyProperty TranslationProperty = DependencyProperty.Register("Translation", typeof(RBTranslation), typeof(TranslationInput));
        /// <summary>
        /// Gets or sets the translation being edited.
        /// </summary>
        /// <value>The translation.</value>
        public RBTranslation Translation {
            get { return base.GetValue(TranslationProperty) as RBTranslation; }
            set { 
                base.SetValue(TranslationProperty, value);
            }
        }

        public static readonly DependencyProperty ShowGoogleTranslateProperty = DependencyProperty.Register("ShowGoogleTranslate", typeof(bool), typeof(TranslationInput), new PropertyMetadata(true));
        /// <summary>
        /// Gets or sets whether the Google translate button is visible.
        /// </summary>
        /// <value><c>true</c> if the Google translate should be shown, otherwise <c>false</c>.</value>
        public bool ShowGoogleTranslate {
            get { return (bool)base.GetValue(ShowGoogleTranslateProperty); }
            set {
                base.SetValue(ShowGoogleTranslateProperty, value);
            }
        }

        public static readonly DependencyProperty ShowWordNetProperty = DependencyProperty.Register("ShowWordNet", typeof(bool), typeof(TranslationInput), new PropertyMetadata(true));
        /// <summary>
        /// Gets or sets whether the WordNet lookup button is visible.
        /// </summary>
        /// <value><c>true</c> if the WordNet lookup should be shown, otherwise <c>false</c>.</value>
        public bool ShowWordNet {
            get { return (bool)base.GetValue(ShowWordNetProperty); }
            set {
                base.SetValue(ShowWordNetProperty, value);
            }
        }

        public static readonly DependencyProperty LanguageCodeProperty = DependencyProperty.Register("LanguageCode", typeof(string), typeof(TranslationInput), new PropertyMetadata(new PropertyChangedCallback(CheckWordNetSupported)));
        /// <summary>
        /// Gets the language code for which this <see cref="TranslationInput"/> allows input.
        /// </summary>
        /// <value>The language code.</value>
        public string LanguageCode {
            get { return (string)base.GetValue(LanguageCodeProperty); }
            set {
                base.SetValue(LanguageCodeProperty, value);
            }
        }

        private static void CheckWordNetSupported(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
            string newCode = (e.NewValue ?? string.Empty).ToString();
            TranslationInput realSender = sender as TranslationInput;
            realSender.ShowWordNet = realSender.ShowWordNet && WordNet.IsLanguageSupported(newCode);
        }

        /// <summary>
        /// Gets or sets a value that determines the order in which elements receive focus when the user navigates through controls by using the TAB key.  This is a dependency property.
        /// </summary>
        /// <value></value>
        /// <returns>
        /// A value that determines the order of logical navigation for a device. The default value is <see cref="F:System.Int32.MaxValue"/>.
        /// </returns>
        public new int TabIndex {
            get { return base.TabIndex; }
            set {
                txtTranslation.TabIndex = value;
                btnToggleEdit.TabIndex = ++value;
                btnFullEditorTranslation.TabIndex = ++value;
                btnFindSimilar.TabIndex = ++value;
                btnWordNet.TabIndex = ++value;
                btnGoogleTranslate.TabIndex = ++value;
                txtComment.TabIndex = ++value;
                btnFullEditorComment.TabIndex = ++value;
                base.TabIndex = ++value;
            }
        }

        /// <summary>
        /// Initializes a new <see cref="TranslationInput"/>.
        /// </summary>
        public TranslationInput() {
            InitializeComponent();
        }

        /// <summary>
        /// Initializes a new <see cref="TranslationInput"/> to edit the specified translation.
        /// </summary>
        /// <param name="info">The CultureInfo of the language for which this TranslationInput allows translation.</param>
        public TranslationInput(CultureInfo info)
            : this() {
            this.LanguageCode = info.Name;
            lblEnglishName.Text = info.EnglishName;
            btnFindSimilar.ToolTip = string.Format("Search for similiar translations using the {0} translation", info.EnglishName);
            //btnWordNet.ToolTip = string.Format("Lookup the definition of Use Google translate to translate the default language into {0}", info.EnglishName);
            btnGoogleTranslate.ToolTip = string.Format("Use Google translate to translate the default language into {0}", info.EnglishName);
        }

        /// <summary>
        /// Focuses the translation textbox.
        /// </summary>
        public void FocusTranslation() {
            txtTranslation.Focus();
        }

        /// <summary>
        /// Adds the binding rule to the Translation textbox.
        /// </summary>
        /// <param name="rule">The rule.</param>
        public void AddBindingRule(ValidationRule rule) {
            Binding bndTranslation = txtTranslation.GetBindingExpression(TextBox.TextProperty).ParentBinding;
            bndTranslation.ValidationRules.Add(rule);
        }

        /// <summary>
        /// Validates the input on the Translation textbox if a binding rule has been added.
        /// </summary>
        /// <returns></returns>
        public bool ValidateInput() {
            bool valid = true;
            Binding bnd = txtTranslation.GetBindingExpression(TextBox.TextProperty).ParentBinding;
            Window parentWindow = Window.GetWindow(this);
            foreach(ValidationRule rule in bnd.ValidationRules) {
                ValidationResult result = rule.Validate(txtTranslation.Text, CultureInfo.CurrentCulture);
                if(!result.IsValid) {
                    DialogBox.Show(parentWindow, result.ErrorContent.ToString(), "Error", DialogBox.DialogBoxType.OK, DialogBox.DialogBoxIcon.Error);
                    valid = false;
                }
            }
            if(!valid) {
                txtTranslation.Focus();
            }
            return valid;
        }

        /// <summary>
        /// Shows the extra controls in the expander.
        /// </summary>
        public void Expand() {
            EditControls.IsExpanded = true;
        }
    }
}
